{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-02-19T02:52:55.965364Z",
     "start_time": "2019-02-19T02:52:55.528878Z"
    },
    "collapsed": true,
    "hide_input": false
   },
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "from torch.autograd import Variable\n",
    "from torch.optim.lr_scheduler import StepLR\n",
    "from torch.utils.data import DataLoader,TensorDataset\n",
    "import torch.utils.data as data\n",
    "import numpy as np\n",
    "import scipy.io as sio\n",
    "import math\n",
    "import argparse\n",
    "import random\n",
    "import os\n",
    "from My_Loss import HardTripletLoss\n",
    "from My_Loss import HardTripletLoss2\n",
    "from My_Loss import HardTripletLoss_D\n",
    "from tensorboardX import SummaryWriter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-02-19T02:52:55.968504Z",
     "start_time": "2019-02-19T02:52:55.966272Z"
    },
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "BATCH_SIZE = 64\n",
    "EPISODE = 200000\n",
    "TEST_EPISODE = 1000\n",
    "LEARNING_RATE =1e-5\n",
    "Weight_Deacy = 1e-6\n",
    "GPU = 0\n",
    "Margin = 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-02-19T02:52:57.031550Z",
     "start_time": "2019-02-19T02:52:55.969595Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "init dataset\n",
      "----------------------------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "print(\"init dataset\")\n",
    "##################################参数##################################################################\n",
    "dataroot = '../data'\n",
    "dataset = 'APY_data'\n",
    "image_embedding = 'res101'               #ResNet101层\n",
    "class_embedding = 'att'         #属性表达 85-d\n",
    "#######################################读取视觉特征###################################################################\n",
    "\n",
    "matcontent = sio.loadmat(dataroot + \"/\" + dataset + \"/\" + image_embedding + \".mat\")  #scipy loadmat\n",
    " \n",
    "feature = matcontent['features'].T         #转置 30478x2048 每一行是一个完整的样本\n",
    "\n",
    "label = matcontent['labels'].astype(int).squeeze() - 1   #matlab begin 1 ,numpy begin 0\n",
    "########################################读取属性特征###########################################################\n",
    "\n",
    "matcontent = sio.loadmat(dataroot + \"/\" + dataset + \"/\" + class_embedding + \"_splits.mat\")\n",
    "\n",
    "    \n",
    "# numpy array index starts from 0, matlab starts from 1\n",
    "trainval_loc = matcontent['trainval_loc'].squeeze() - 1    #squeeze()去掉维度中的1 AxBx1 --->AxB\n",
    "\n",
    "test_seen_loc = matcontent['test_seen_loc'].squeeze() - 1\n",
    "test_unseen_loc = matcontent['test_unseen_loc'].squeeze() - 1\n",
    "\n",
    "attribute = matcontent['att'].T    #转置 50x85 每行是整个属性向量\n",
    "\n",
    "x = feature[trainval_loc]                      # train_features trainval里面是图片的编号 begin with 0 ，19832个\n",
    "train_label = label[trainval_loc].astype(int)  # train_label  int类型没变 每个图片的lable 19832个\n",
    "train_id = np.unique(train_label)\n",
    "\n",
    "att = attribute[train_label]                   # train attributes 每个图片的属性 19832个\n",
    "\n",
    "########################add negative pairs#######################\n",
    "#x_negative = np.empty_like(x)\n",
    "#x_negative_label = np.empty_like(train_label)\n",
    "#print(x.shape[0])\n",
    "\n",
    "#for i in range(x.shape[0]):\n",
    "#    pick=np.random.choice(np.where(train_label[i]!=train_id)[0], replace=True)\n",
    "#    x_negative[i] = x[pick]\n",
    "#    x_negative_label[i] = train_label[pick]\n",
    "    \n",
    "x_test = feature[test_unseen_loc]                   # test_feature 5685个\n",
    "test_label = label[test_unseen_loc].astype(int)     # test_label   5685个\n",
    "\n",
    "x_test_seen = feature[test_seen_loc]                #test_seen_feature 4958个\n",
    "test_label_seen = label[test_seen_loc].astype(int)  # test_seen_label  4958个\n",
    "    \n",
    "test_id = np.unique(test_label)                     # test_id  10个类 ，unique去重\n",
    "att_pro = attribute[test_id]                        # test_attribute 每一类的属性向量 10x85\n",
    "\n",
    "# train set\n",
    "train_features = torch.from_numpy(x)   #np-->tensor\n",
    "#train_fearures_negative = torch.from_numpy(x_negative)\n",
    "\n",
    "sample_attributes=[]\n",
    "train_label = torch.from_numpy(train_label).unsqueeze(1) #每张图片的属性转化 ，unsqueeze(1)就是插入到第一维度 AxB维-->Ax1xB\n",
    "#train_negative_label = torch.from_numpy(x_negative_label).unsqueeze(1)\n",
    "# attributes\n",
    "all_attributes = np.array(attribute)  #所有50类属性转变为numpy数组???属性向量仍然用的numpy类型 没有转化为pytorch\n",
    "#print(all_attributes)\n",
    "    \n",
    "#print('-'*50)\n",
    "attributes = torch.from_numpy(attribute) \n",
    "#print(attribute)\n",
    "# test set\n",
    "\n",
    "test_features = torch.from_numpy(x_test)\n",
    "#print(test_features.shape)\n",
    "\n",
    "test_label = torch.from_numpy(test_label).unsqueeze(1)\n",
    "#print(test_label.shape)\n",
    "\n",
    "testclasses_id = np.array(test_id)\n",
    "#print(testclasses_id.shape)\n",
    "\n",
    "test_attributes = torch.from_numpy(att_pro).float()\n",
    "#print(test_attributes.shape)\n",
    "\n",
    "test_seen_features = torch.from_numpy(x_test_seen)\n",
    "#print(test_seen_features.shape)\n",
    "\n",
    "test_seen_label = torch.from_numpy(test_label_seen)\n",
    "\n",
    "train_data = TensorDataset( train_label, train_features )\n",
    "#train_data = TensorDataset(train_label, train_features, train_fearures_negative)\n",
    "\n",
    "#################here need new code to make triplet data#####################\n",
    "print('-'*100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-02-19T02:52:57.035572Z",
     "start_time": "2019-02-19T02:52:57.032712Z"
    },
    "collapsed": true,
    "hide_input": false
   },
   "outputs": [],
   "source": [
    "from my_net_3 import AttributeNetwork\n",
    "from my_net_3 import MetricNetwork"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-02-19T02:52:58.667293Z",
     "start_time": "2019-02-19T02:52:57.036840Z"
    },
    "hide_input": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "init networks\n",
      "----------------------------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "# init network\n",
    "print(\"init networks\")\n",
    "attribute_network = AttributeNetwork(64,1600,2048)  #85d属性 1024隐藏层 2048输出 85d到2048d\n",
    "metric_network = MetricNetwork(2048,1600,2048)\n",
    "#triplet_network = TripletNetwork(attribute_network, metric_network)  #metric learning   \n",
    "attribute_network.cuda(GPU) \n",
    "metric_network.cuda(GPU)\n",
    "#attribute_network_optim = torch.optim.Adam(attribute_network.parameters(), lr=LEARNING_RATE, weight_decay=1e-5)\n",
    "#优化器adam 学习率 正则1e-5\n",
    "\n",
    "#attribute_network_scheduler = StepLR(attribute_network_optim, step_size=200000, gamma=0.5)\n",
    "#学习率每200k步 乘0.5\n",
    "attribute_network_optim = torch.optim.Adam(attribute_network.parameters(), lr=LEARNING_RATE,weight_decay=Weight_Deacy)\n",
    "metric_network_optim = torch.optim.Adam(metric_network.parameters(), lr=LEARNING_RATE,weight_decay=Weight_Deacy)\n",
    "#\n",
    "#triplet_network_optim = torch.optim.SGD(triplet_network.parameters(), lr=LEARNING_RATE,momentum=0.9 , \n",
    "#                                         weight_decay=Weight_Deacy)\n",
    "\n",
    "attribute_network_scheduler = StepLR(attribute_network_optim , step_size=40000 , gamma=0.5)\n",
    "metric_network_scheduler = StepLR(metric_network_optim , step_size=40000 , gamma=0.5)\n",
    "#\n",
    "print('-'*100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-02-19T02:52:58.674529Z",
     "start_time": "2019-02-19T02:52:58.668385Z"
    },
    "collapsed": true,
    "hide_input": true
   },
   "outputs": [],
   "source": [
    "def compute_accuracy(test_features, test_label, test_id, test_attributes):\n",
    "    \n",
    "    test_data = TensorDataset(test_features, test_label)\n",
    "    test_batch = 32\n",
    "    test_loader = DataLoader(test_data, batch_size=test_batch, shuffle=False)\n",
    "    total_rewards = 0\n",
    "\n",
    "    sample_labels = test_id\n",
    "    sample_attributes = test_attributes\n",
    "    class_num = sample_attributes.shape[0]\n",
    "    test_size = test_features.shape[0]\n",
    "\n",
    "    print(\"class num:\", class_num)\n",
    "\n",
    "    for batch_features,batch_labels in test_loader:\n",
    "\n",
    "        batch_size = batch_labels.shape[0]\n",
    "        batch_features_ext = torch.from_numpy(batch_features.numpy().repeat(class_num, 0))\n",
    "        batch_features_ext = metric_network(Variable(batch_features_ext).cuda(GPU).float())  # 32*1024\n",
    "\n",
    "        #print(batch_features_ext)\n",
    "\n",
    "        sample_features = metric_network(attribute_network(Variable(sample_attributes).cuda(GPU).float()))\n",
    "        sample_features_ext = sample_features.repeat(batch_size, 1)\n",
    "        #print(sample_features_ext.shape)\n",
    "\n",
    "\n",
    "        relations = F.pairwise_distance(batch_features_ext, sample_features_ext, 2).view(-1, class_num)\n",
    "        re_batch_labels = []\n",
    "        for label in batch_labels.numpy():\n",
    "            index = np.argwhere(sample_labels == label)\n",
    "            re_batch_labels.append(index[0][0])\n",
    "        re_batch_labels = torch.cuda.LongTensor(re_batch_labels)\n",
    "\n",
    "\n",
    "        _, predict_labels = torch.min(relations.data, 1)\n",
    "        #print(predict_labels)\n",
    "        rewards = [1 if predict_labels[j] == re_batch_labels[j] else 0 for j in range(batch_size)]\n",
    "        total_rewards += np.sum(rewards)\n",
    "    test_accuracy = total_rewards/1.0/test_size\n",
    "    return  test_accuracy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-02-19T02:52:58.684880Z",
     "start_time": "2019-02-19T02:52:58.676080Z"
    },
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def compute_accuracy_per_class(test_features, test_label, test_id, test_attributes,cos_sim = False):\n",
    "    \n",
    "    test_data = TensorDataset(test_features, test_label)\n",
    "    test_batch = 32\n",
    "    test_loader = DataLoader(test_data, batch_size=test_batch, shuffle=False)\n",
    "    total_rewards = 0\n",
    "    #print(test_features.size())\n",
    "    sample_labels = test_id\n",
    "    sample_attributes = test_attributes\n",
    "    class_num = sample_attributes.shape[0]\n",
    "    test_size = test_features.shape[0]\n",
    "    per_class_num = np.zeros(class_num)\n",
    "    per_class_true= np.zeros(class_num)\n",
    "\n",
    "    print(\"class num:\", class_num)\n",
    "\n",
    "    for batch_features,batch_labels in test_loader:\n",
    "\n",
    "        batch_size = batch_labels.shape[0]\n",
    "        batch_features_ext = torch.from_numpy(batch_features.numpy().repeat(class_num, 0))\n",
    "        batch_features_ext = metric_network(Variable(batch_features_ext).cuda(GPU).float())  # 32*1024\n",
    "\n",
    "\n",
    "        sample_features = metric_network(attribute_network(Variable(sample_attributes).cuda(GPU).float()))\n",
    "        sample_features_ext = sample_features.repeat(batch_size, 1)\n",
    "\n",
    "        if cos_sim:\n",
    "            relations = F.cosine_similarity(batch_features_ext, sample_features_ext).view(-1, class_num)\n",
    "        else:\n",
    "            relations = F.pairwise_distance(batch_features_ext, sample_features_ext, 2).view(-1, class_num)\n",
    "        re_batch_labels = []\n",
    "        for label in batch_labels.numpy():\n",
    "            index = np.argwhere(sample_labels == label)\n",
    "            re_batch_labels.append(index[0][0])\n",
    "        re_batch_labels_id, batch_per_num = np.unique(re_batch_labels , return_counts=True) \n",
    "        re_batch_labels = torch.cuda.LongTensor(re_batch_labels)\n",
    "        \n",
    "        for each in range(re_batch_labels_id.size):\n",
    "            #print(re_batch_labels_id[each])\n",
    "            #print(batch_per_num[each])\n",
    "            per_class_num[re_batch_labels_id[each]] = per_class_num[re_batch_labels_id[each]] + batch_per_num[each]\n",
    "        #print(re_batch_labels_id)\n",
    "        #print('-'*100)\n",
    "        #print(batch_per_num)\n",
    "        #print('-'*100)\n",
    "\n",
    "\n",
    "        _, predict_labels = torch.min(relations.data, 1)\n",
    "        for j in range(batch_size):\n",
    "            if predict_labels[j] == re_batch_labels[j]:\n",
    "                per_class_true[re_batch_labels[j]] = per_class_true[re_batch_labels[j]] + 1\n",
    "            \n",
    "        \n",
    "        \n",
    "    per_accuracy = per_class_true[np.nonzero(per_class_num)] / per_class_num[np.nonzero(per_class_num)]\n",
    "    \n",
    "\n",
    "    test_accuracy = np.sum(per_accuracy)/1.0/np.count_nonzero(per_class_num)\n",
    "    \n",
    "    #print(np.count_nonzero(per_class_num))\n",
    "    return  test_accuracy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-02-19T02:53:28.842331Z",
     "start_time": "2019-02-19T02:52:58.686539Z"
    },
    "code_folding": [],
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "training...\n",
      "episode: 1 loss tensor(3.0008, device='cuda:0', grad_fn=<DivBackward0>)\n",
      "loss_zero_number=  0\n",
      "Testing...\n",
      "class num: 12\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/workspace/wanghai/anaconda3/envs/pytorch/lib/python3.5/site-packages/torch/nn/functional.py:1332: UserWarning: nn.functional.sigmoid is deprecated. Use torch.sigmoid instead.\n",
      "  warnings.warn(\"nn.functional.sigmoid is deprecated. Use torch.sigmoid instead.\")\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "class num: 32\n",
      "class num: 32\n",
      "zsl: 0.09812837539889104\n",
      "gzsl: unseen=0.0287 , seen=0.0472 , h=0.0357\n",
      "____________________________________________________________________________________________________\n",
      "episode: 200 loss tensor(2.9944, device='cuda:0', grad_fn=<DivBackward0>)\n",
      "loss_zero_number=  0\n",
      "Testing...\n",
      "class num: 12\n",
      "class num: 32\n",
      "class num: 32\n",
      "zsl: 0.30224655456851834\n",
      "gzsl: unseen=0.0283 , seen=0.6538 , h=0.0542\n",
      "____________________________________________________________________________________________________\n",
      "episode: 400 loss tensor(2.9322, device='cuda:0', grad_fn=<DivBackward0>)\n",
      "loss_zero_number=  0\n",
      "Testing...\n",
      "class num: 12\n",
      "class num: 32\n",
      "class num: 32\n",
      "zsl: 0.23225453392098686\n",
      "gzsl: unseen=0.0321 , seen=0.6185 , h=0.0611\n",
      "____________________________________________________________________________________________________\n",
      "episode: 600 loss tensor(2.6797, device='cuda:0', grad_fn=<DivBackward0>)\n",
      "loss_zero_number=  0\n",
      "Testing...\n",
      "class num: 12\n",
      "class num: 32\n",
      "class num: 32\n",
      "zsl: 0.1638797796095439\n",
      "gzsl: unseen=0.0861 , seen=0.4264 , h=0.1433\n",
      "____________________________________________________________________________________________________\n"
     ]
    },
    {
     "ename": "KeyboardInterrupt",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-8-b9a4c7532d29>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     17\u001b[0m     \u001b[0mbatch_attributes_ext\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mbatch_attributes\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrepeat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mBATCH_SIZE\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     18\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 19\u001b[0;31m     \u001b[0mbatch_features_ext\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mVariable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbatch_features_ext\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcuda\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mGPU\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m  \u001b[0;31m# 32*2048\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     20\u001b[0m     \u001b[0mbatch_attributes_ext\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mVariable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbatch_attributes_ext\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcuda\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mGPU\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     21\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
     ]
    }
   ],
   "source": [
    "print(\"training...\")\n",
    "last_accuracy = 0.0\n",
    "loss_zero_num = 0\n",
    "#writer = SummaryWriter()\n",
    "for episode in range(EPISODE):\n",
    "    #attribute_network.train()\n",
    "    attribute_network_scheduler.step(episode)\n",
    "    metric_network_scheduler.step(episode)\n",
    "\n",
    "    train_loader = DataLoader(train_data, batch_size=BATCH_SIZE, shuffle=True)\n",
    "\n",
    "    batch_labels, batch_features = train_loader.__iter__().next()\n",
    "    batch_id = np.unique(batch_labels)\n",
    "\n",
    "    batch_attributes = torch.Tensor([all_attributes[i] for i in batch_id]).squeeze(1)\n",
    "    batch_features_ext = torch.from_numpy(batch_features.numpy().repeat(batch_id.size, 0))\n",
    "    batch_attributes_ext = batch_attributes.repeat(BATCH_SIZE, 1)\n",
    "\n",
    "    batch_features_ext = Variable(batch_features_ext).cuda(GPU).float()  # 32*2048\n",
    "    batch_attributes_ext = Variable(batch_attributes_ext).cuda(GPU)\n",
    "    \n",
    "\n",
    "    re_batch_labels = []\n",
    "    for label in batch_labels.numpy():\n",
    "        index = np.argwhere(batch_id == label)\n",
    "        re_batch_labels.append(index[0][0])\n",
    "    re_batch_labels = torch.cuda.LongTensor(re_batch_labels)\n",
    "    re_batch_labels = Variable(re_batch_labels).cuda(GPU)\n",
    "    \n",
    "\n",
    "\n",
    "    criterion = HardTripletLoss(margin = Margin).cuda(GPU)\n",
    "    triplet_loss= criterion(metric_network(attribute_network(batch_attributes_ext)), \n",
    "                            metric_network(batch_features_ext), re_batch_labels)\n",
    "    if triplet_loss == 0:\n",
    "        loss_zero_num = loss_zero_num + 1\n",
    "    metric_network.zero_grad()\n",
    "    attribute_network.zero_grad()\n",
    "    \n",
    "    triplet_loss.backward()\n",
    "    \n",
    "    attribute_network_optim.step()\n",
    "    metric_network_optim.step()\n",
    "    \n",
    "    if (episode+1)%200 == 0 or episode==0:\n",
    "        print(\"episode:\", episode+1, \"loss\", triplet_loss)\n",
    "        print('loss_zero_number= ',loss_zero_num)\n",
    "        #writer.add_scalar('data/loss_zero_number', loss_zero_num, episode)\n",
    "        loss_zero_num = 0\n",
    "        #writer.add_scalar('data/loss', triplet_loss, episode)\n",
    "    if (episode+1)%200 == 0 or episode==0:\n",
    "        print(\"Testing...\")\n",
    "        #attribute_network.eval()\n",
    "        zsl_accuracy = compute_accuracy_per_class(test_features, test_label, test_id, test_attributes)\n",
    "        gzsl_unseen_accuracy = compute_accuracy_per_class(test_features, test_label, np.arange(32), attributes)\n",
    "        gzsl_seen_accuracy = compute_accuracy_per_class(test_seen_features, test_seen_label, np.arange(32), attributes)\n",
    "        H = 2 * gzsl_seen_accuracy * gzsl_unseen_accuracy / (gzsl_unseen_accuracy + gzsl_seen_accuracy)\n",
    "        #H2 = 2 * gzsl_seen_accuracy2 * gzsl_unseen_accuracy2 / (gzsl_unseen_accuracy2 + gzsl_seen_accuracy2)\n",
    "        print('zsl:', zsl_accuracy)\n",
    "        #print('zsl:', zsl_accuracy2)\n",
    "        print('gzsl: unseen=%.4f , seen=%.4f , h=%.4f' % (gzsl_unseen_accuracy , gzsl_seen_accuracy, H))\n",
    "        #print('gzsl: unseen=%.4f , seen=%.4f , h=%.4f' % (gzsl_unseen_accuracy2 , gzsl_seen_accuracy2, H2))\n",
    "        print('_'*100)\n",
    "        #writer.add_scalar('data/zsl_accuracy', zsl_accuracy, episode)\n",
    "        #writer.add_scalar('data/gzsl_unseen_accuracy', gzsl_unseen_accuracy, episode)\n",
    "        #writer.add_scalar('data/gzsl_seen_accuracy', gzsl_seen_accuracy, episode)\n",
    "        dir(triplet_loss.grad_fn)\n",
    "        #writer.add_scalar('data/H', H, episode)\n",
    "#writer.export_scalars_to_json(\"./test.json\")\n",
    "#writer.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "hide_input": false,
  "kernelspec": {
   "display_name": "pytorch",
   "language": "python",
   "name": "pytorch"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
